/** 
 * plpsh 
 * Copyright (C) 2009 - Luís Paulo Faina Garcia 
 * Copyright (C) 2009 - Rafael Mitsuo Maki.
 *
 * plpsh - A basic shell developed in Operational Systems 2 discipline.
 *
 * Authors: Luís Paulo Faina Garcia
 *          Rafael Mitsuo Maki
 *
 * Date: Apr, 2009
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * This code was developed by students of the Computing Engineering
 * undergraduate course of Universidade de São Paulo, São Carlos/SP,
 * Brasil. The initial developers of the original code are Luís Paulo
 * Faina Garcia <lpfgarcia@gmail.com> and Rafael Mitsuo Maki
 * <rafamitsuom@gmail.com>.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>

//List struct for args
struct lista {
	char myarg[1024];       //real arg 
	struct lista *prox;	//pointer to another list struct
};

//List struct for jobs - this work for save the corent jobs in the shell
struct jobs {
	int num; //number of job
	int pid; //PID of the job
	int status; //status of job
	char name[128]; //simple name of the job to informate the user        
	struct jobs *prox; //pointer to another job
};

//List struct for process - this work to save the process executed in the shell
struct process {
	int num; //number of process
	int pid; //PID of the process
	int status; //status of the process - normaly executaded
	char name[128]; //simple name of the job to informate the user        
	struct process *prox; //pointer to another process
};


//functions definitions
int cd(char ***vet);
int exitt();
void read_help(char *buffer);
void show_help(char *buffer);
int exectcmdfore(char ***vet, struct process **proc);
int exectcmdback(char ***vet, struct jobs **job);
int killexect(char ***vet, struct jobs **job);
int addcmdhistory(char **str, struct lista **list);
int printcmdhistory(struct lista **list);
int savecmdhistory(struct lista **list);
int parser(char ***vet, struct lista **list);
int addjobs(struct jobs ***job, char *name, int pid, int status);
int searchjobs(struct jobs ***job, int *pid, int *status, int number);
int removejobs(struct jobs ***job, int pid);
int printjobs(struct jobs **job);
int addprocess(struct process ***proc, char *name, int pid, int status);
int searchprocess(struct process ***proc, int *pid, int *status, int number);
int removeprocess(struct process ***proc, int pid);
int printprocess(struct process **proc);
void redirect_out1(char ***vet, int pos);
void redirect_out2(char ***vet, int pos);
void redirect_in1(char ***vet, int pos);
void redirect_in2(char ***vet, int pos);
void exec_pipe(char ***vet, int pos);
int check_redirects(char ***vet);
int fg(char ***vet, struct jobs **job, struct process **proc);
int bg(char ***vet, struct jobs **job, struct process **proc);
int run_background(char ***vet);

//main function
int main (int argc, char **argv){

	int start=1, redirect, background; 
	char **vet; //save the args here 
	char *str; //firt place which save the commad
	char buffer[4096]; //simple buffer to help
	struct lista *list; //do the list of args for history
	struct jobs *job; //do the list of jobs
	struct process *proc; //do the list of process

	list = NULL; //init the list
	job = NULL; //init the list
	proc = NULL; //init the list

	//function that hold the ctrl+c signal
	void ctrlc (int signum){

		//simple struct to walk in the list of process
		struct process *aux; 
		aux = proc;

		//find the last process in the list
		if(aux != NULL){
			while(aux->prox != NULL)
				aux = aux->prox;
		}
		else
			printf("don't exist process\n");

		//send the signal to terminate and don't do anything more! 
		kill(aux->pid, SIGTERM);
		//bye bye process
	}

	//function that hold the ctrl+z signal
	void ctrlz (int signum){

		//simple struct to walk in the list of process
		struct process *aux; 
		aux = proc;

		//find the last process in the list
		if(aux != NULL){
			while(aux->prox != NULL)
				aux = aux->prox;
		}
		else
			printf("don't exist process\n");

		//send the signal to stop 
		kill(aux->pid, SIGSTOP);
		//process is stop
	}

	//job-control signals
	signal(SIGINT,ctrlc);
	signal(SIGTSTP,ctrlz);

	//call the function that read the help file
	read_help(buffer);

	//main loop - this repeat while the usar don't enter with command exit
	while(start){
		printf("[plpsh]$ ");
		//reserve memory for str
		str = malloc(1024*sizeof(char)); 
		//save the string in str
		fgets(str, 1024, stdin); 
		//cut the end of string to remove the '\n'
		str[strlen(str)-1]= '\0'; 

		//adding the command to the plpsh history
		addcmdhistory(&str , &list);
		//calling the parser function - this will cut the string and save in **vet
		parser(&vet, &list);

		redirect = 0;
		background = 0;

		//if something is put in vet
		if(vet[0] != NULL){
			//verify is there are redirections or pipes in the command
			redirect = check_redirects(&vet);
			//verify if the command will run in background
			background = run_background(&vet);
			if(redirect == 0){
				//if the command will run in background, call the background execution function
				if(background == 1) 
					exectcmdback(&vet, &job);
				//built in - change the current directory
				else if(strcmp(vet[0], "cd") == 0)
					cd(&vet);
				//built in - close the plpsh
				else if(strcmp(vet[0], "exit") == 0)
					start = exitt();
				//built in - show the plpsh history
				else if(strcmp(vet[0], "history") == 0)
					printcmdhistory(&list);
				//built in - show plpsh help	  
				else if(strcmp(vet[0], "help") == 0)
					show_help(buffer);
				//built in - show plpsh jobs
				else if(strcmp(vet[0], "jobs") == 0)
					printjobs(&job);
				//built in - show plpsh process
				else if(strcmp(vet[0], "process") == 0)
					printprocess(&proc);
				//put a process to run in foreground
				else if(strcmp(vet[0], "fg") == 0)
					fg(&vet, &job, &proc);
				//put a process to run in background
				else if(strcmp(vet[0], "bg") == 0)
					bg(&vet, &job, &proc);
				//kill a job
				else if(strcmp(vet[0], "killjobs") == 0) 
					killexect(&vet, &job);
				//execute basics commands in /bin or /usr/bin or /usr/games/
				else                                     
					exectcmdfore(&vet, &proc);
			}
		}
		//free the memory of str
		free(str);
	}
	//save the history in corrent work
	savecmdhistory(&list);

return 0;
}

/* 
* Command cd - Change working directory
* This function recive triple pointer vet to use when will change the corrent diretory.
* The function who we use is chdir()
*/
int cd(char ***vet){

	//recive the second arg 
	return chdir(vet[0][1]);
}

/* 
* Command exit - go out of the shell
* This function don't recive args
* The function send "zero" to "start" in main
*/
int exitt() {

	//return "zero" to start
	return 0;
}

/* 
* Command read_help - function that read the help file
* This function recive buffer
*/
void read_help(char *buffer) {

	int i, file_in;

	//buffer inicialization
	for(i = 0; i < 4096; i++){
		buffer[i] = '\0';
	}

	//openning the help file
	file_in = open("help", O_RDONLY);

	if(file_in == -1){
		write(1, "Help File no found!\n", 21);
	}
	else{
		//reading the file
		read(file_in,buffer, 4096);
	}
	close(file_in);
}

/* 
* Command show_help - function help of plpsh (show the help file saved into a buffer)
* This function recive buffer
*/
void show_help(char *buffer) {
	write(1, buffer, 4096);
}

/* 
* Command exectcmdfore - execute a process in foreground and add call addprocess to add the pid in list
* This function recive triple pointer vet to execute the command and a head of process list.
*/
int exectcmdfore(char ***vet, struct process **proc) {

	int child, status;

	//parents
	if(child = fork()){
		//add the process in a list
		addprocess(&proc, vet[0][0], child, status);
		//continue the execute
		waitpid(child, &status, WUNTRACED);
	}
	//child
	else{
		//execute command
		execvp(vet[0][0], vet[0]);
		//if command not found
		printf("plpsh: %s: command not found\n", vet[0][0]);
		exit(0);
	}

return 0;
}

/* 
* Command exectcmdback - execute a job in background and add the call addjobs to add the pid in list
* This function recive triple pointer vet to execute the command and a head of job list
*/
int exectcmdback(char ***vet, struct jobs **job) {

	int i, child, status;

	//formating the vector of args
	for(i=0; vet[0][i] != NULL; i++)
		if(strcmp(vet[0][i], "&") == 0)
			vet[0][i] = NULL;		

	//parents
	if(child = fork()){
		//add the job in a list
		addjobs(&job, vet[0][0], child, status);
		//wait the execute
		waitpid(child, &status, WNOHANG);
	}
	//child
	else{
		//Execute command
		execvp(vet[0][0], vet[0]);
		//if command not found
		printf("plpsh: %s: command not found\n", vet[0][0]);
		exit(0);
	}

return 0;
}

/* 
* Command killexect - function with realy kill a job
* This function recive triple pointer vet to execute the command kill and a head of job list to remove from there
*/
int killexect(char ***vet, struct jobs **job){

	int pid, number, status;

	//receive a number of job
	number = atoi(vet[0][1]);

	//search in a list of jobs and return the pid
	searchjobs(&job, &pid, &status, number);

	//send signal to end the job
	kill(pid, SIGTERM);
	//remove the job of list
	removejobs(&job, pid);

return 0;
}

/* 
* Command addcmdhistory - add the string in list of args - history
* This function recive a pointer to str and a head of lista list to add there
*/
int addcmdhistory(char **str, struct lista **list){

	int i, j;
	struct lista *aux, *temp;

	//reserve memory for the temp
	temp = malloc(sizeof(struct lista));
	temp->prox = NULL;

	//copy the string
	strcpy(temp->myarg, *str);

	//add in a list
	if(*list == NULL)
		*list = temp;
	else {
		aux = *list;
		*list = temp;
		temp->prox = aux;
	}  

return 0;
}

/* 
* Command printcmdhistory - print the list of args - history
* This function recive a head of lista list to walk in the list
* The aux pointer will walk and print 
*/
int printcmdhistory(struct lista **list){

	int i;
	struct lista *aux;

	//the head of list
	aux = *list;    

	//walk in the list
	for(i=0; aux != NULL; i++){
		printf("%d - %s\n", i, aux->myarg);
		aux = aux->prox;
	}

return 0;
}

/* 
* Command savecmdhistory - Save the commands list in a file - history
* This function recive a head of lista list to walk in the list
* The aux pointer will walk and save in a file
*/
int savecmdhistory(struct lista **list){

	int i;
	struct lista *aux;
	FILE *fl;

	//open the file
	fl = fopen("history_plpsh", "a+b");
	//the head of list
	aux = *list;    

	//walk in the list saving
	for(i=0; aux != NULL; i++){
		aux->myarg[strlen(aux->myarg)] = '\n';
		fputs(aux->myarg, fl);
		aux = aux->prox;
	}  

return 0;
}

/* 
* Command parser - Parser the string
* This function recive triple pointer vet and a head of lista list
* This will separate the important things and save in a vet
*/
int parser(char ***vet, struct lista **list){

	int i, j, l, num;
	struct lista *aux;

	//the head of list
	aux = *list;
	num = 1;

	//reserve memory for vet
	vet[0] = malloc(num*sizeof(char*));

	//walk in the string
	for(i=0, j=0; aux->myarg[i] != '\0' && aux->myarg[i] != '\n'; i++){

		//case the string is diferente of '\" - case have this in a list: "Hello World"'
		if(aux->myarg[i] == '\"'){
			i++;
			//realloc memory for vet
			vet[0] = realloc(vet[0], (num)*sizeof(char*));
			vet[0][num-1] = malloc(1024*sizeof(char));      
			//parser the string
			for(l=0; aux->myarg[i] != '\"'; i++, l++)
				vet[0][j][l] = aux->myarg[i];
			vet[0][j][l] = '\0';
			j++;
			num++;	
		//case the string is different of space - ' '
		} else if(aux->myarg[i] != ' '){
			//realloc memory for vet
			vet[0] = realloc(vet[0], (num)*sizeof(char*));
			vet[0][num-1] = malloc(1024*sizeof(char));      
			//parser the string
			for(l=0; aux->myarg[i] != ' ' && aux->myarg[i] != '\0'; i++, l++)
				vet[0][j][l] = aux->myarg[i];
			vet[0][j][l] = '\0';
			j++;
			num++;
		}
	}
	//the last recive NULL
	vet[0][j] = NULL;

return 0;
}

/* 
* Command addjobs - add a job in the list
* This function recive triple pointer to a head of job list, a nickname, the pid and the status of a job
* This will add in the end of the list
*/
int addjobs(struct jobs ***job, char *name,  int pid, int status){

	int cont;
	struct jobs *aux, *temp;

	//reserve memory for temp
	temp = malloc(sizeof(struct jobs));
	//complete the temp
	temp->num = 0;
	temp->pid = pid;
	temp->status = status;
	strcpy(temp->name, name);
	temp->prox = NULL;
       
  	//add in the end of the list
	if(**job == NULL)
		**job = temp;
	else {
		aux = **job;
		cont = aux->num;
		while(aux->prox != NULL) {
			aux = aux->prox;
			cont = aux->num;
		}
		aux->prox = temp;
		temp->num = ++cont;            
	}  

return 0;
}

/* 
* Command searchjobs - search a job in the list and return the pid and status of job
* This function recive triple pointer to a head of job list, the pid, the status, and the number of job
* This will search the number and return somethings
*/
int searchjobs(struct jobs ***job, int *pid, int *status, int number){

	struct jobs *aux;
	//head of the list
	aux = **job;

	//search the number
	while(aux != NULL && aux->num != number)
		aux = aux->prox;

	if(aux != NULL) {
		//return the pid of job
		if(aux->num == number) {
			*pid = aux->pid;
			*status = aux->status;
		}
	}
	//return error
	else
		return -1;

return 0;
}

/* 
* Command removejobs - remove the job of the list
* This function recive triple pointer to a head of job list and the pid of job
* This will search and remove 
*/
int removejobs(struct jobs ***job, int pid){

	struct jobs *aux, *temp;

	//find and remove
	if(**job == NULL)
		printf("null list\n");
	else {
		aux = **job;
		temp = aux->prox;
		if(aux->pid == pid)
			**job = temp;
		else {
			while(temp != NULL && temp->pid != pid){
				aux = aux->prox;
				temp = temp->prox;
			}
			if(temp->pid == pid)
				aux->prox = temp->prox;
		}
	}  

return 0;
}

/* 
* Command removejobs - print the jobs in the list
* This function recive triple pointer to a head of job
* This will print the number, the pid, the status and the name - all list
*/
int printjobs(struct jobs **job){

	int i;
	struct jobs *aux;

	/*Head of the list.*/
	aux = *job;    

	/*Print the jobs.*/
	for(i=0; aux != NULL; i++){
		printf("num = %d pid = %d status = %d name = %s...\n", aux->num, aux->pid, aux->status, aux->name);
		aux = aux->prox;
	}

return 0;
}

/* 
* Command addprocess - add a process in the list
* This function recive triple pointer to a head of process list, a nickname, the pid and the status of a process
* This will add in the end of the list
*/
int addprocess(struct process ***proc, char *name,  int pid, int status){

	int cont;
	struct process *aux, *temp;

	//reserve memory for temp
	temp = malloc(sizeof(struct process));
	temp->num = 0;
	temp->pid = pid;
	temp->status = status;
	strcpy(temp->name, name);
	temp->prox = NULL;
       
  	//add in the end of the list
	if(**proc == NULL)
		**proc = temp;
	else {
		aux = **proc;
		cont = aux->num;
		while(aux->prox != NULL) {
			aux = aux->prox;
			cont = aux->num;
		}
		aux->prox = temp;
		temp->num = ++cont;            
	}  

return 0;
}

/* 
* Command searchprocess - search a process in the list and return the pid and status of process
* This function recive triple pointer to a head of process list, the pid, the status, and the number of job
* This will search the number and return somethings
*/
int searchprocess(struct process ***proc, int *pid, int *status,  int number){

	struct process *aux;
	//head of the list
	aux = **proc;

	//search the number
	while(aux != NULL && aux->num != number)
		aux = aux->prox;

	if(aux != NULL){
		//return the pid of process
		if(aux->num == number){
			*pid = aux->pid;
			*status = aux->status;
		}
	}
	//return error
	else
		return -1;

return 0;
}

/* 
* Command removeprocess - remove the process of the list
* This function recive triple pointer to a head of process list and the pid of process
* This will search and remove 
*/
int removeprocess(struct process ***proc, int pid){

	struct process *aux, *temp;

	//find and remove
	if(**proc == NULL)
		printf("null list\n");
	else {
		aux = **proc;
		temp = aux->prox;
		if(aux->pid == pid)
			**proc = temp;
		else {
			while(temp != NULL && temp->pid != pid){
				aux = aux->prox;
				temp = temp->prox;
			}
			if(temp->pid == pid)
				aux->prox = temp->prox;
		}
	}  

return 0;
}

/* 
* Command printprocess - print the process in the list
* This function recive triple pointer to a head of process
* This will print the number, the pid, the status and the name - all list
*/
int printprocess(struct process **proc){

	int i;
	struct process *aux;

	//head of the list
	aux = *proc;

	//print the process
	for(i=0; aux != NULL; i++){
		printf("num = %d pid = %d status = %d name = %s...\n", aux->num, aux->pid, aux->status, aux->name);
		aux = aux->prox;
	}

return 0;
}

/* 
* Command redirect_out1 - Function of > (output redirection)
* This function recive triple pointer and the integer pos
* This will do the ">"
*/
void redirect_out1(char ***vet, int pos){

	int fd, child;

	//parents
	if(child = fork())
		wait(NULL);
	//child
	else {
		//open the file
		if( (fd = open(vet[0][pos+1], O_CREAT | O_WRONLY, S_IWUSR | S_IRUSR)) < 0)
			perror("Cannot create/open file\n");
		//change the file descriptor
		else {
			//close the output
			close(STDOUT_FILENO);
			dup(fd);
			close(fd);
		}
		/*Execute the command.*/                
		execvp(vet[0][pos-1], NULL);
	}
}

/* 
* Command redirect_out2 - Function of >> (output redirection)
* This function recive triple pointer and the integer pos
* This will do the ">>"
*/
void redirect_out2(char ***vet, int pos){

	int fd, child;

	//parents
	if(child = fork())
		wait(NULL);
	//child
	else {
		//open the file
		if( (fd = open(vet[0][pos+1], O_CREAT | O_APPEND | O_WRONLY, S_IWUSR | S_IRUSR)) < 0)
			perror("Cannot create/open file\n");
		//change the file descriptor	
		else {
			//close the output
			close(STDOUT_FILENO);
			dup(fd);
			close(fd);
		}
		//execute the command                   
		execvp(vet[0][pos-1], NULL);
	}
}

/* 
* Command redirect_in1 - Function of < (input redirection)
* This function recive triple pointer and the integer pos
* This will do the "<"
*/
void redirect_in1(char ***vet, int pos){

	int fd, child;

	//parents
	if(child = fork())
		wait(NULL);
	//child
	else {
		//open the file
		if( (fd = open(vet[0][pos+1],O_RDONLY, S_IWUSR | S_IRUSR)) < 0)
			perror("Cannot create/open file\n");
		//change the file descriptor	
		else {
			//close the input
			close(STDIN_FILENO);
			dup(fd);
			close(fd);
		}
		//execute the command  
		execvp(vet[0][pos-1], NULL);
	}
}

/* 
* Command redirect_in1 - Function of << (input redirection)
* This function recive triple pointer and the integer pos
* This will do the "<<"
*/
void redirect_in2(char ***vet, int pos){

	int fd, child;
	char str[1024];
	FILE *fl;

	//parents
	if(child = fork())
		wait(NULL);
	else {
		//open a temp. file
		fl = fopen(vet[0][pos+1], "w");
		while(strcmp(str, vet[0][pos+1]) != 0){
			printf(">");
			fgets(str, 1024, stdin);
			fputs(str, fl);
			str[strlen(str)-1] = '\0';                              
		}
		fclose(fl);
		//open the file
		if( (fd = open(vet[0][pos+1],O_RDONLY, S_IWUSR | S_IRUSR)) < 0)
			perror("Cannot create/open file\n");
		//change the file descriptor
		else {
			close(STDIN_FILENO);
			dup(fd);
			close(fd);
		}
		//remove file
		remove(vet[0][pos+1]);
		//execute the command
		execvp(vet[0][pos-1], NULL);
	}
}

/* 
* Command exec_pipe - Function tha executes the pipe (rediretion of the output of a program to the input of another program
* This function recive triple pointer and the integer pos
* This will do the "|"
*/
void exec_pipe(char ***vet, int pos){
	
	int pipefd[2];
	char **command1, **command2;	

	//creating the pipe
	if(pipe(pipefd) < 0){
		perror("Error to create the pipe\n");
		exit(EXIT_FAILURE);
	} else{
		//child 1
		if(fork() == 0){
			//close the standard output, duplicate the pipe file descriptor and closing files descriptors
			close(STDOUT_FILENO);
			dup(pipefd[1]);
			close(pipefd[1]);
			close(pipefd[0]);
			//execute the command
			execvp(vet[0][pos-1], NULL);
			printf("plpsh: %s: command not found\n", vet[0][pos-1]);
			exit(0);
		}
		//child 2
		if(fork() == 0){
			//close the standard input, duplicate the pipe file descriptor and closing files descriptors
			close(STDIN_FILENO);
			dup(pipefd[0]);
			close(pipefd[0]);
			close(pipefd[1]);
			//execute the command
			execvp(vet[0][pos+1], NULL);
			printf("plpsh: %s: command not found\n", vet[0][pos+1]);
			exit(0);
		}
		//parent
		else
			wait(NULL);
	}
}

/* 
* Command check_redirects - Check the redirects and pipes and call the functions
* This function recive triple pointer
*/
int check_redirects(char ***vet){

	int ret = 0, i, j;

	//walk in the vector of args
	for(i = 0; vet[0][i] != NULL; i++){
		if(strcmp(vet[0][i], ">") == 0){
			ret = 1;
			redirect_out1(vet, i);
		}
		else if(strcmp(vet[0][i], ">>") == 0){
			ret = 1;
			redirect_out2(vet, i);
		}
		else if(strcmp(vet[0][i], "<") == 0){
			ret = 1;
			redirect_in1(vet, i);
		}
		else if(strcmp(vet[0][i], "<<") == 0){
			ret = 1;
			redirect_in2(vet, i);
		}
		else if(strcmp(vet[0][i], "|") == 0){
			ret = 1;
			exec_pipe(vet, i);
		}
	}
	
return ret;
}

/* 
* Command fg - Funtion for execute in foreground
* This function recive triple pointer, job list and proc list
* This will put the job in foregroung
*/
int fg(char ***vet, struct jobs **job, struct process **proc){

	int pid, number, status;
	
	//transform string to integer
	number = atoi(vet[0][1]);

	//Search the pid with job #number
	if( searchjobs(&job, &pid, &status, number) == 0){

		removejobs(&job, pid);
		//wait the end
		waitpid(pid, &status, WUNTRACED);
		//add in list of process
		addprocess(&proc, vet[0][1], pid, status);
		//signal to pid
		kill(pid, SIGCONT);


	}
	else
		printf("plpsh: fg: %d: job don't exist\n", number);

return 0;
}

/* 
* Command bg - Funtion for execute in background
* This function recive triple pointer, job list and proc list
* This will put the process in backgroung
*/
int bg(char ***vet, struct jobs **job, struct process **proc){

	int pid, number, status;

	//transform string to integer
	number = atoi(vet[0][1]);        

	//search the pid with job #number
	if( searchprocess(&proc, &pid, &status, number) == 0) {

		removeprocess(&proc, pid);
		//wait the execute
		waitpid(pid, &status, WNOHANG);
		//add in list of jobs
		addjobs(&job, vet[0][1], pid, status);
		//signal to pid
		kill(pid, SIGCONT);
	}
	else
		printf("plpsh: bg: %d: job don't exist\n", number);

return 0;
}

/* 
* Command bg - Function that verify if the process will be executed in background
* This function recive triple pointer
*/
int run_background(char ***vet) {

	int i;

	for(i = 0; vet[0][i] != NULL; i++)
		if(strcmp(vet[0][i], "&") == 0)
			return 1;

return 0;
}

